.TH DYLD_DEBUG 3 "April 21, 2000" "Apple Computer, Inc."
.SH NAME
dyld debug \- programmatic interface for debugging a task using the dynamic link editor
.SH SYNOPSIS
.nf
.PP
#include <mach-o/dyld_debug.h>
#include <mach-o/dyld.h>
extern enum dyld_debug_return _dyld_debug_defining_module(
	task_t target_task,
	unsigned long send_timeout,
	unsigned long rcv_timeout,
	boolean_t inconsistent_data_ok,
	char *name,
	struct dyld_debug_module *module);
.sp .5
extern enum dyld_debug_return _dyld_debug_is_module_bound(
	task_t target_task,
	unsigned long send_timeout,
	unsigned long rcv_timeout,
	boolean_t inconsistent_data_ok,
	struct dyld_debug_module module,
	boolean_t *bound);
.sp .5
extern enum dyld_debug_return _dyld_debug_bind_module(
	task_t target_task,
	unsigned long send_timeout,
	unsigned long rcv_timeout,
	boolean_t inconsistent_data_ok,
	struct dyld_debug_module module);
.sp .5
extern enum dyld_debug_return _dyld_debug_module_name(
	task_t target_task,
	unsigned long send_timeout,
	unsigned long rcv_timeout,
	boolean_t inconsistent_data_ok,
	struct dyld_debug_module module,
	char **image_name,
	unsigned long *image_nameCnt,
	char **module_name,
	unsigned long *module_nameCnt);
.sp .5
extern enum dyld_debug_return _dyld_debug_subscribe_to_events(
	task_t target_task,
	unsigned long send_timeout,
	unsigned long rcv_timeout,
	boolean_t inconsistent_data_ok,
	void (*dyld_event_routine)(struct dyld_event event));
.sp .5
extern enum dyld_debug_return _dyld_debug_add_event_subscriber(
	task_t target_task,
	unsigned long send_timeout,
	unsigned long rcv_timeout,
	boolean_t inconsistent_data_ok,
	port_t subscriber);
.sp .5
extern boolean_t _dyld_event_server(
	struct _dyld_event_message_request *request,
	struct _dyld_event_message_reply *reply);
.sp .5
extern void _dyld_event_server_callback(
	port_t subscriber,
	struct dyld_event event);
.sp .5
extern void _dyld_debug_set_error_func(
	void (*func)(struct dyld_debug_error_data *e));
.sp .5
extern enum dyld_debug_return _dyld_debug_make_runnable(
	mach_port_t target_task,
	struct _dyld_debug_task_state *state);
.sp .5
extern enum dyld_debug_return _dyld_debug_restore_runnable(
	mach_port_t target_task,
	struct _dyld_debug_task_state *state);
.sp .5
extern enum dyld_debug_return _dyld_debug_task_from_core(
	NSObjectFileImage coreFileImage,
	mach_port_t *core_task);
.fi
.SH DESCRIPTION
.PP
These routines are the programmatic interface for debugging or examining a task
that is using the dynamic link editor.  Using these routines allows one to get
accurate information on which symbols (and from which library or image they
come from) are being used by a target task.
.PP
These routines communicate with the target_task being debugged
with mach messages.  The parameters target_task, send_timeout, rcv_timeout
and inconsistent_data_ok have the same meaning for all the routines.
All the routines return the same return code type which is interpreted the
same for all routines.
.PP
.I target_task
is the task port for the task which is being debugged.
.PP
.I send_timeout
and
.I rcv_timeout
are the mach message send and receive time out values in milliseconds to be
used with msg_rpc(2).
.PP
.I
inconsistent_data_ok
indicates if it is ok to attempt the operation even though the state of the
dynamic linker in the target task is inconsistent.  All of these calls suspend
all threads in the target task during the duration of the calls. Then they first
attempt to finish any current dynamic linking operation in process, there by
getting the dynamic linker into a consistent state.  If the operation is done
successfully and
.I inconsistent_data_ok
was
.SM FALSE
it is assured the results are consistent.  If the operation fails with
.I inconsistent_data_ok
.SM FALSE
it can be retried with
.I inconsistent_data_ok
.SM TRUE
to possibly get the information.  Even if
.I inconsistent_data_ok
is
.SM TRUE
the operation may still fail with the return code
.SM DYLD_INCONSISTENT_DATA
depending on the state of the dynamic linker in the target task and the
operation to be performed.
.PP
.I _dyld_debug_defining_module
is passed a symbol name and returns which module the symbol name is being or
would be used from.  If the symbol does not exist in the target_task this
returns
.SM DYLD_INVALID_ARGUMENTS.
.PP
.I _dyld_debug_is_module_bound
is passed a dyld_debug_module struct and sets
.I bound
to
.SM TRUE
if the module is bound and
.SM FALSE
otherwise.  If the module does not refer to a valid module
.SM DYLD_INVALID_ARGUMENTS
is returned.
.PP
.I _dyld_debug_bind_module
binds the modules specified by dyld_debug_module into the target task.
If the module does not refer to a valid module
.SM DYLD_INVALID_ARGUMENTS
is returned.  This will return
.SM DYLD_FAILURE
if there is a dynamic linking operation in progress that could not be first
completed without error.
This routine can cause the task to exit if when binding the specified module
it results in an undefined symbol, a multiply defined symbol or other link edit
error and the target task does not handle the error.
.I _dyld_debug_bind_module
should be used with this in mind.
.PP
.I _dyld_debug_module_name
returns the image name and module name for the specified dyld_debug_module in
the target task.
If the module does not refer to a valid module
.SM DYLD_INVALID_ARGUMENTS
is returned.  This will return
.SM DYLD_FAILURE
if there is a dynamic linking operation in progress that could not be first
completed without error.
The names are returned as pointers to vm_allocated memory. Their sizes are also
returned so the memory can be vm_deallocated when no longer needed.
Tempting as it might be, this can not be called from the function
passed to _dyld_debug_subscribe_to_events as the mach message queues will fill
and the calls will time out.
.PP
.I _dyld_debug_subscribe_to_events
creates a new thread that will call the specified dyld_event_routine when
dynamic link events occur in the target task.  These events are described below.
.PP
.I _dyld_debug_add_event_subscriber
adds the
.I subscriber
port to the list of event ports that dyld event messages are sent to.  This is
just a different interface to get dynamic link events on a mach port rather
than using
.I _dyld_debug_subscribe_to_events
which creates a new thread.
.PP
.I _dyld_event_server
is the mig generated routine to dispatch dyld event messages that can be used if
the
.I _dyld_debug_add_event_subscriber
interface is used.  This routine will call the routine
.I _dyld_event_server_callback
which must be provided if
.I _dyld_event_server
is used.
.PP
.I _dyld_debug_set_error_func
is called with a pointer to a function,
.I func,
which will then be called if there are any errors in subsequent calls to other
dyld debug routines.
This is to provide more detailed information when the APIs of the dyld debug
interfaces fail (return
.SM DYLD_FAILURE).
The
.I e
argument is a pointer to a dyld_debug_error_data structure as defined by
.B <mach-o/dyld_debug.h>
(shown below) and into which information is placed concerning the error.
.RS
.nf
struct dyld_debug_error_data {
    enum dyld_debug_return dyld_debug_return;
    kern_return_t mach_error;
    int dyld_debug_errno;
    unsigned long local_error;
    char *file_name;
    unsigned long line_number;
}
.fi
.RE
.PP
The local_error field is a unique number for each possible error condition
in the source code in that makes up the dyld debug APIs.
The file_name and line_number fields are filled in with the the source file name
and line number for the files in the Darwin cctools project in the libdyld
sub-directory which is where the dyld debug APIs are implemented.
The field dyld_debug_return is filled in with that would be returned by the API
(usually
.SM DYLD_FAILURE).
The other fields will be zero or filled in by the
error code from the mach system call, or
.SM UNIX
system call that failed.
This is intended to help diagnose problems with the kernel like not starting
the dyld debug thread in the target task.
.PP
.I _dyld_debug_make_runnable
is automaticly called before sending messages to the dynamic link editor but
when the
.I _dyld_debug_add_event_subscriber
API is used by the debugger,
.IR gdb (1)
for example, it may have the task and threads suspended and may need to call
.I _dyld_debug_make_runnable
directly.
.I _dyld_debug_make_runnable
assures that the dyld debug thread is the only runnable thread in the task to
receive the message.  It also assures that the debugging thread is indeed
runnable if it was suspended.  To be able to restore the state of the task this
function changes, the parameter
.I state,
is passed in as a pointer to _dyld_debug_task_state structure and the state
changed state is saved into that structure.
.PP
.I _dyld_debug_restore_runnable
is automaticly called after sending messages to the dynamic link editor but
again a debugger like
.IR gdb (1)
may need to directly call it.  It undoes what
.I _dyld_debug_make_runnable
did to the task and puts it back the way it was.  These functions will make sure
each thread in the remote task is suspended and resumed the same number of
times, so in the end the suspend count of each individual thread is the same.
.PP
_dyld_debug_task_from_core
is used to create a task from a core file in which the dyld debug API can then
be used with that task.  The task port is indirectly returned through the
parameter
.I core_task.
The core file is represented as the parameter
.I coreFileImage
which is returned from a sucessfull to
.IR NSCreateCoreFileImageFromFile (3).
.SH DYLD EVENTS
.PP
If
.I _dyld_debug_subscribe_to_events
or
.I _dyld_debug_add_event_subscriber
is used dynamic link events will be sent to the
.I dyld_event_routine
or
.I _dyld_event_server_callback
respectively.
The dyld_event structure parameter describes the dynamic link event that
happened in the target task.  The event field of the dyld_event structure
specified the type of the event and the arg field describes the module(s) or
image for the event.  The dyld_debug_module of the arg's for non-library
modules always have module_index field of 0.
The possible event types are as follows:
.PP
The
.SM DYLD_IMAGE_ADDED
event is sent when a new image is brought into the target task.  These images
include the dynamic linker itself, the executable image, dynamic shared
libraries that get loaded and objects loaded by NSLinkModule.  For this event
only the arg[0] field of the dyld_event structure is used for the image and the
module_index has no meaning since this event is for the entire image.
.PP
A
.SM DYLD_MODULE_BOUND
event is sent for each module that is bound into the target task.
For this event only the arg[0] field of the dyld_event structure is used to
identify the module being bound.
.PP
A
.SM DYLD_MODULE_REMOVED
event is sent for each module that is removed in the target task via an
NSUnLinkModule call done by the target task.
For this event only the arg[0] field of the dyld_event structure is used to
identify the module being unlinked.
.PP
A
.SM DYLD_MODULE_REPLACED
event is sent for each module that is replaced in the target task via an
NSReplaceModule call done by the target task.
For this event the arg[0] field of the dyld_event structure is used to
identify the module that was replaced and the arg[1] field identifies the new
module that replaced it.
.PP
A
.SM DYLD_IMAGE_REMOVED
event is sent for each image that is removed in the target task via an
NSUnLinkModule call (without the
.SM  NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
option specified) done by the target task.  For this event only the arg[0]
field of the dyld_event structure is used to identify the module being removed.
.SH RETURN CODES
.TP
.SM DYLD_SUCCESS
Indicates the operation and the communication with the target task was
successful.
.TP
.SM DYLD_INCONSISTENT_DATA
Indicates the operation was not attempted because the state of the dynamic
linker was able to be brought into a consistent state.
.TP
.SM DYLD_INVALID_ARGUMENTS
Indicates the operation failed because the arguments to the operation were
invalid.
.TP
.SM DYLD_FAILURE
Indicates the operation or the communication with the target task was
unsuccessful.
